package com.mediacatalyst.core {
	import flash.display.Loader;	import flash.events.Event;	import flash.events.EventDispatcher;	import flash.events.IOErrorEvent;	import flash.events.ProgressEvent;	import flash.media.Sound;	import flash.media.SoundLoaderContext;	import flash.net.URLRequest;	import flash.system.ApplicationDomain;	import flash.system.LoaderContext;	import flash.utils.Dictionary;	
	/**
	 * @author doornen
	 */
	public class Assetsbooklet 
	{
		private static var _data:IdentifiableXML;
		private static var _preloaded:Dictionary;
		private static var _listeners:EventDispatcher;

		public function Assetsbooklet(){
			if(_data == null)
				_data = new IdentifiableXML();
			if(_preloaded == null)
				_preloaded = new Dictionary(false);
			if(_listeners == null)
				_listeners = new EventDispatcher();
		}
		
		public function setNewXML(key:String,value:XML):void{
			_data.add(key,value);
		}
		
		public function getAsset(_xml:String,id:String,asPathString:Boolean=false):Object{
			var xml:XML = _data.retrieve(_xml);
			if(xml!=null){
				var obj:Object = _getObject(_xml,id);
				if(obj!=null)
					return obj;
				var path:String = xml.*.( hasOwnProperty( "@id" ) && @id == id ).@src;
				if(asPathString)
					return path;
				var clazz:Class = _getLoader(path);
				if(clazz != null){
					obj = new clazz();
					EventDispatcher(obj).addEventListener(Event.COMPLETE,_complete);
					EventDispatcher(obj).addEventListener(IOErrorEvent.IO_ERROR,_error);
					EventDispatcher(obj).addEventListener(ProgressEvent.PROGRESS,_progress);
					if(clazz == Loader)
						Loader(obj).load(new URLRequest(path),new LoaderContext(true,ApplicationDomain.currentDomain));
					else if(clazz == Sound)
						Sound(obj).load(new URLRequest(path),new SoundLoaderContext(1000,true));
					if(_preloaded[xml] == null)
						_preloaded[xml] = new Dictionary(false); 
					_preloaded[xml][id] = obj;
					return obj;
				}
			}
			return null;
		}
		
		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
			_listeners.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
			_listeners.addEventListener(type, listener, useCapture);
		}
		
		private function _complete(e:Event):void{
			_listeners.dispatchEvent(e);
		}
		
		private function _error(e:IOErrorEvent):void{
			_listeners.dispatchEvent(e);
		}
		
		private function _progress(e:ProgressEvent):void{
			_listeners.dispatchEvent(e);
		}
		
		private function _getObject(xml:String,id:String):Object{
			if(_preloaded[xml] != null && 
				_preloaded[xml][id] != null)
				return _preloaded[xml][id];
			return null;
		}
		
		private function _getLoader(path:String):Class{
			var ext:String = path.substr(path.lastIndexOf(".")+1).toLowerCase();
			switch (ext){
				case "mp3":
					return Sound;
				case "swf":
				case "jpg":
				case "png":
				case "jpeg":
				case "gif":
					return Loader;
				case "flv":
					return null;
			}
			return null;
		}
		
		public function getAttribute(_xml:String,id:String,attr:String): String {
			var xml:XML = _data.retrieve(_xml);
			if(xml!=null){
				return xml.*.( hasOwnProperty( "@id" ) && @id == id ).attribute(attr);
			} else
				return "";
		}
		
		public function size(xml:String):uint{
			var xm:XML = _data.retrieve(xml);
			if(xm==null)
				return 0;
			return xm.children().length();
		}
		
		public function sizeByKey(xml:String,key:String):uint{
			var xm:XML = _data.retrieve(xml);
			if(xm==null)
				return 0;
			var list:XMLList = xm.*.( new RegExp('^'+key+'.*','g')['test'](@id) );
			return list.length();
		}
		
		public function getXML( key : String ) : XML
		{
			return _data.getXML(key);
		}	
	}
}
import flash.utils.Dictionary;
class IdentifiableXML{
	private var _storage:Dictionary;
	
	public function IdentifiableXML(){
		_storage = new Dictionary( false );
	}
	
	public function add(key:String,value:XML):Boolean{
		key = key.toLowerCase();
		if(inUse(key) || exists(value))
			return false;
		else 
			_storage[key] = value;
			return true;
	}
	
	public function retrieve(key:String):XML{
		if(!_storage.hasOwnProperty(key))
			return null;
		return _storage[key.toLowerCase()];
	}
	
	public function exists(xml:XML):Boolean{
		for each(var storage_xml:XML in _storage){
			if(storage_xml == xml)
				return true;
		}
		return false;
	}
	
	public function inUse(key:String):Boolean{
		key = key.toLowerCase();
		for(var storage_key:String in _storage){
			if(storage_key == key)
				return true;
		}
		return false;
	}
	
	public function getXML(key:String):XML{
		key = key.toLowerCase();
		for(var storage_key:String in _storage){
			if(storage_key == key)
				return _storage[key];
		}
		return null;
	}
}